package com.codeman.crawl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codeman.business.book.domain.Book;
import com.codeman.business.book.domain.BookContent;
import com.codeman.business.book.domain.BookIndex;
import com.codeman.business.book.mapper.BookCategoryMapper;
import com.codeman.business.book.mapper.BookMapper;
import com.codeman.business.book.service.IBookContentService;
import com.codeman.business.book.service.IBookIndexService;
import com.codeman.crawl.service.ICrawlBookService;

import com.codeman.crawl.utils.Constants;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @author Administrator
 */
@Service
@RequiredArgsConstructor
public class CrawBookServiceImpl implements ICrawlBookService {

    private final BookMapper bookMapper;

    private final BookCategoryMapper bookCategoryMapper;

    private final IBookIndexService bookIndexService;

    private final IBookContentService bookContentService;

    @Override
    public boolean queryIsExistByBookNameAndAuthorName(String bookName, String authorName) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_name", bookName)
                .eq("author_name", authorName);
        return bookMapper.selectCount(queryWrapper) > 0;
    }

    @Override
    public void updateCrawlProperties(Long id, Integer sourceId, String bookId) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Book book = new Book();
        book.setCrawlSourceId(sourceId);
        book.setCrawlBookId(bookId);
        bookMapper.update(book, queryWrapper);
    }

    @Override
    public String queryCatNameByCatId(int catId) {
        return bookCategoryMapper.selectById(catId).getName();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList) {
        if (!queryIsExistByBookNameAndAuthorName(book.getBookName(), book.getAuthorName())) {

            if (bookIndexList.size() > 0) {

                //保存小说主表

                book.setCreateTime(new Date());
                bookMapper.insert(book);
                //批量保存目录和内容
                bookIndexService.saveBatch(bookIndexList);

                bookContentService.saveBatch(bookContentList);

            }
        }
    }

    @Override
    public List<Book> updateNeedUpdateBook(Date startDate, int limit) {
        List<Book> books = queryNeedUpdateBook(startDate, limit);
        if (books.size() > 0) {
            //更新最后抓取时间为当前时间
            QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", books.stream().map(bk -> bk.getId()).collect(Collectors.toList()));
            Book book = new Book();
            book.setCrawlLastTime(new Date());
            bookMapper.update(book, queryWrapper);
        }
        return books;
    }

    private List<Book> queryNeedUpdateBook(Date startDate, int limit) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        String sql = "limit " + limit;
        queryWrapper.isNotNull("crawl_source_id")
                .ge("last_index_update_time", startDate)
                .orderByAsc("crawl_last_time")
                .last(sql);
        return bookMapper.selectList(queryWrapper);
    }

    @Override
    public Map<Integer, BookIndex> queryExistBookIndexMap(Long bookId) {
        QueryWrapper<BookIndex> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", bookId);
        List<BookIndex> bookIndexs = bookIndexService.list(queryWrapper);
        if (bookIndexs.size() > 0) {
            return bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
        }
        return new HashMap<>(0);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList, Map<Integer, BookIndex> existBookIndexMap) {
        for (int i = 0; i < bookIndexList.size(); i++) {
            BookIndex bookIndex = bookIndexList.get(i);
            BookContent bookContent = bookContentList.get(i);


            if (!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
                //插入
                bookIndexService.save(bookIndex);
                bookContentService.save(bookContent);
            } else {
                //更新
                bookIndexService.updateById(bookIndex);
                QueryWrapper<BookContent> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("index_id", bookContent.getIndexId());
                BookContent updateBC = new BookContent();
                updateBC.setContent(bookContent.getContent());
                bookContentService.update(updateBC, queryWrapper);
            }


        }

        //更新小说主表
        book.setBookName(null);
        book.setAuthorName(null);
        if (Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
            book.setVisitCount(null);
        }
        bookMapper.updateById(book);

    }

    @Override
    public void updateCrawlLastTime(Long bookId) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", bookId);
        Book book = new Book();
        book.setCrawlLastTime(new Date());
        bookMapper.update(book, queryWrapper);
    }

    @Override
    public Book queryBookByBookNameAndAuthorName(String bookName, String authorName) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_name", bookName)
                .eq("author_name", authorName);
        List<Book> books = bookMapper.selectList(queryWrapper);
        if (books.size() > 0) {
            return books.get(0);
        }

        return null;
    }
/*

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList) {
        if(!queryIsExistByBookNameAndAuthorName(book.getBookName(),book.getAuthorName())) {

            if(bookIndexList.size()>0) {

                //保存小说主表

                book.setCreateTime(new Date());
                bookMapper.insertSelective(book);

                //批量保存目录和内容
                bookIndexMapper.insertMultiple(bookIndexList);
                bookContentMapper.insertMultiple(bookContentList);

            }
        }


    }

    @Override
    public List<Book> queryNeedUpdateBook(Date startDate, int limit) {
        List<Book> books = bookMapper.queryNeedUpdateBook(startDate, limit);
        if(books.size()>0) {
            //更新最后抓取时间为当前时间
            bookMapper.updateCrawlLastTime(books, new Date());
        }
        return books;
    }

    @Override
    public Map<Integer, BookIndex> queryExistBookIndexMap(Long bookId) {
        List<BookIndex> bookIndexs = bookIndexMapper.selectMany(select(BookIndexDynamicSqlSupport.id,BookIndexDynamicSqlSupport.indexNum,BookIndexDynamicSqlSupport.indexName,BookIndexDynamicSqlSupport.wordCount)
                .from(BookIndexDynamicSqlSupport.bookIndex)
                .where(BookIndexDynamicSqlSupport.bookId,isEqualTo(bookId))
                .build()
                .render(RenderingStrategies.MYBATIS3));
        if (bookIndexs.size() > 0) {
            return  bookIndexs.stream().collect(Collectors.toMap(BookIndex::getIndexNum, Function.identity()));
        }
        return new HashMap<>(0);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateBookAndIndexAndContent(Book book, List<BookIndex> bookIndexList, List<BookContent> bookContentList, Map<Integer, BookIndex> existBookIndexMap) {
        for (int i = 0; i < bookIndexList.size(); i++) {
            BookIndex bookIndex = bookIndexList.get(i);
            BookContent bookContent = bookContentList.get(i);


            if(!existBookIndexMap.containsKey(bookIndex.getIndexNum())) {
                //插入
                bookIndexMapper.insertSelective(bookIndex);
                bookContentMapper.insertSelective(bookContent);
            }else{
                //更新
                bookIndexMapper.updateByPrimaryKeySelective(bookIndex);
                bookContentMapper.update(update(BookContentDynamicSqlSupport.bookContent)
                        .set(BookContentDynamicSqlSupport.content)
                        .equalTo(bookContent.getContent())
                        .where(BookContentDynamicSqlSupport.indexId,isEqualTo(bookContent.getIndexId()))
                        .build()
                        .render(RenderingStrategies.MYBATIS3));
            }


        }

        //更新小说主表
        book.setBookName(null);
        book.setAuthorName(null);
        if(Constants.VISIT_COUNT_DEFAULT.equals(book.getVisitCount())) {
            book.setVisitCount(null);
        }
        bookMapper.updateByPrimaryKeySelective(book);

    }

    @Override
    public void updateCrawlLastTime(Long bookId) {
        Book book = new Book();
        book.setId(bookId);
        book.setCrawlLastTime(new Date());
        bookMapper.updateByPrimaryKeySelective(book);
    }

    @Override
    public Book queryBookByBookNameAndAuthorName(String bookName, String authorName) {
        List<Book> books = bookMapper.selectMany(select(BookDynamicSqlSupport.id).from(BookDynamicSqlSupport.book)
                .where(BookDynamicSqlSupport.bookName, isEqualTo(bookName))
                .and(BookDynamicSqlSupport.authorName, isEqualTo(authorName))
                .build()
                .render(RenderingStrategies.MYBATIS3));

        if(books.size()>0){
            return books.get(0);
        }

        return null;

    }

    */
/**
 * 查询最后的章节
 * *//*

    private BookIndex queryLastIndex(Long bookId) {
        return bookIndexMapper.queryLastIndex(bookId);
    }

    */
/**
 * 查询小说总字数
 * *//*

    private Integer queryTotalWordCount(Long bookId) {

        return bookMapper.queryTotalWordCount(bookId);

    }
*/
}
